from bayes_opt import BayesianOptimization
from sklearn.model_selection import KFold, cross_validate
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier as RFR
import numpy as np
# def bayes_opt_validation(params_best):
#     reg = RFR(n_estimators = int(params_best['n_estimators'])
#               , max_depth = int(params_best['max_depth'])
#               , max_features = int(params_best['max_features'])
#               , min_impurity = params_best['min_impurity']
#               , random_state = 1412
#               ,verbose=False
#               ,n_jobs=-1
#               )
#     cv = KFlod(n_splits=5, shuffle=True, random_state=1412)
#     validation_loss = cross_validate(reg, )

def bayesopt_object(n_estimators,max_depth,max_features,min_impurity):
    reg = RFR(n_estimators=int(n_estimators)
              , max_depth=int(max_depth)
              , max_features=int(max_features)
              , min_impurity_decrease=min_impurity
              , random_state=1412
              , verbose=False
              , n_jobs=-1
              )
    cv = KFold(n_splits=5, shuffle=True, random_state=1412)

    validation_loss = cross_validate(reg,load_wine().data,load_wine().target
                                     ,scoring="neg_root_mean_squared_error"
                                     ,cv=cv
                                     ,verbose=False
                                     ,n_jobs=-1
                                     ,error_score='raise')
    return np.mean(validation_loss["test_score"])

param_grid_simple = {
    'n_estimators':(80,100)
    ,'max_depth' :(10,25)
    ,'max_features' :(10,20)
    ,'min_impurity':(0,1)
}

def param_bayes_opt(init_points,n_iter):

    opt= BayesianOptimization(bayesopt_object #需要优化的目标函数
                              ,param_grid_simple #备选参数空间
                              ,random_state=1412) #随机种子，实际 无法控制
    opt.maximize(init_points=init_points #抽取初始观测值
                 ,n_iter=n_iter)#总共观测次数

    params_best = opt.max["params"]
    score_best = opt.max["target"]

    print("best params",params_best)
    print("best cvscore",score_best)

    return params_best,score_best
param_bayes_opt(20,200)